package com.kalua.list.dbaccess.user;

import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
import static com.datastax.driver.core.querybuilder.QueryBuilder.in;
import static com.datastax.driver.core.querybuilder.QueryBuilder.set;
import static com.kalua.list.dbaccess.DAOConstants.ACCOUNT_REF_COLUMN_NAME;
import static com.kalua.list.dbaccess.user.UserCredentialsRowMapper.PASSWORD_COL_NAME;
import static com.kalua.list.dbaccess.user.UserCredentialsRowMapper.SALT_COL_NAME;
import static com.kalua.list.dbaccess.user.UserCredentialsRowMapper.USER_CREDENTIALS_COL_FAMILY_NAME;
import static java.util.stream.Collectors.toList;

import java.util.Collection;

import org.springframework.cassandra.core.RowMapper;
import org.springframework.data.cassandra.core.CassandraTemplate;

import com.datastax.driver.core.Statement;
import com.datastax.driver.core.querybuilder.Insert;
import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.kalua.list.dbaccess.AbstractCRUDDAO;
import com.kalua.list.domainmodel.UUIDIdentifier;
import com.kalua.list.domainmodel.security.UserCredentials;


public class UserCredentialsDAOImpl 	extends AbstractCRUDDAO<UserCredentials, UUIDIdentifier> 
															implements UserCredentialsDAO {

	public UserCredentialsDAOImpl(CassandraTemplate template) 
	{ super(template); }

	@Override
	protected Statement buildInsertStatement(UserCredentials credentials) {
		Insert insert = QueryBuilder.insertInto(USER_CREDENTIALS_COL_FAMILY_NAME)
								.value(ACCOUNT_REF_COLUMN_NAME, credentials.getId().getValue())
								.value(PASSWORD_COL_NAME, credentials.getPassword())
								.value(SALT_COL_NAME, credentials.getSalt())				
								.ifNotExists();		
		return insert;
	}

	@Override
	protected RowMapper<UserCredentials> getRowMapper() 
	{ return new UserCredentialsRowMapper(); }
	
	@Override
	protected Statement buildMultiRowSelect(Object[] keys) {
		Statement statement = QueryBuilder.select().all()
								.from(USER_CREDENTIALS_COL_FAMILY_NAME)
								.where(in(ACCOUNT_REF_COLUMN_NAME, keys));
		return statement;
	}
	
	@Override
	protected Statement buildUpdateStatement(UserCredentials entity) {
		Statement statement = QueryBuilder.update(USER_CREDENTIALS_COL_FAMILY_NAME)
		        .with(set(PASSWORD_COL_NAME, entity.getPassword()))
				.and(set(SALT_COL_NAME, entity.getSalt()))
		        .where(eq(ACCOUNT_REF_COLUMN_NAME, entity.getId().getValue()));
		return statement;
	}
	
	@Override
	protected Object[] toObjectArray(Collection<UUIDIdentifier> keys) {
		Object[] result =  
			keys.stream().map(n -> n.getValue()).collect(toList()).toArray();
		return result; 
	}
	
	@Override
	protected Statement buildReadAllStatement() {
		Statement statement = QueryBuilder.select().all()
		        							.from(USER_CREDENTIALS_COL_FAMILY_NAME);
		return statement;
	}

	@Override
	protected Statement buildDeleteStatement(UUIDIdentifier id) {
		Statement statement = QueryBuilder.delete()
		        .from(USER_CREDENTIALS_COL_FAMILY_NAME)
		        .where(eq(ACCOUNT_REF_COLUMN_NAME, id.getValue()));
		return statement;
	}

	protected Statement buildReadStatement(UUIDIdentifier id) {
		Statement statement = QueryBuilder.select().all()
		        							.from(USER_CREDENTIALS_COL_FAMILY_NAME)
		        							.where(eq(ACCOUNT_REF_COLUMN_NAME, id.getValue()));
		return statement;
	}
}